using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using MvcCms.Service.Code;
using MvcCms.Data;
using System.Globalization;

namespace System
{
    /// <summary>
    ///
    /// </summary>
    public static class StringExtensions
    {

        public static string Left(this string str, int count)
        {
            if (string.IsNullOrEmpty(str) || count < 1)
                return string.Empty;
            else
                return str.Substring(0, Math.Min(count, str.Length));
        }

        private static readonly Regex UrlReplacementExpression = new Regex(@"[^0-9a-z \-]*",
               RegexOptions.Compiled |
               RegexOptions.IgnoreCase |
               RegexOptions.Singleline |
               RegexOptions.CultureInvariant);

        /// <summary>
        /// Tries the trim.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <returns></returns>
        public static string TryTrim(this string s)
        {
            if (s == null)
                return string.Empty;

            return s.Trim();
        }

        /// <summary>
        /// Creates the hash algorithm.
        /// </summary>
        /// <param name="hashName">Name of the hash.</param>
        /// <returns></returns>
        private static HashAlgorithm CreateHashAlgorithm(string hashName)
        {
            switch (hashName.ToLower())
            {
                case "crc32":
                    return new Crc32();

                default:
                    return HashAlgorithm.Create(hashName);
            }
        }

        /// <summary>
        /// Toes the hash.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <returns></returns>
        public static byte[] ToHash(this string content)
        {
            return ToHash("MD5");
        }

        /// <summary>
        /// Toes the hash string.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="hashName">Name of the hash.</param>
        /// <returns></returns>
        public static byte[] ToHash(this string content, string hashName)
        {
            if (content == null)
                throw new ArgumentNullException("content");

            HashAlgorithm algorithm = CreateHashAlgorithm(hashName);
            byte[] buffer = algorithm.ComputeHash(Encoding.Default.GetBytes(content));
            return buffer;
        }

        /// <summary>
        /// Toes the hash.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <returns></returns>
        public static string ToHashString(this string content)
        {
            return ToHashString(content, "MD5");
        }

        /// <summary>
        /// Toes the hash string.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="hashName">Name of the hash.</param>
        /// <returns></returns>
        public static string ToHashString(this string content, string hashName)
        {
            byte[] buffer = ToHash(content, hashName);
            var builder = new StringBuilder(buffer.Length * 2);

            foreach (byte b in buffer)
                builder.Append(b.ToString("x2"));

            return builder.ToString();
        }

        /// <summary>
        /// Toes the hash int64.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <returns></returns>
        public static byte[] ToHashInt64(this string content)
        {
            return ToHashInt64("MD5");
        }

        /// <summary>
        /// Toes the hash int64.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="hashName">Name of the hash.</param>
        /// <returns></returns>
        public static long ToHashInt64(this string content, string hashName)
        {
            byte[] buffer = ToHash(content, hashName);
            return BitConverter.ToInt64(buffer, 0);
        }

        public static string ToAccounting(this decimal amount)
        {
            if (amount < 0)
            {
                return "<span style='color:red;'>" + amount.ToString("c") + "</span>";
            }
            else
            {
                return amount.ToString("c");
            }
        }
        public static string ToMoney(this decimal? amount)
        {
            if (amount.HasValue)
            {
                return amount.GetValueOrDefault().ToString("#0.00");
            }
            else
            {
                return string.Empty;
            }
        }
        public static string ToMoney(this decimal amount)
        {
            return amount.ToString("#0.00");
        }
        public static string ConvertUrlsToLinks(this string msg)
        {
            string regex = @"((www\.|(http|https|ftp|news|file)+\:\/\/)[&#95;.a-z0-9-]+\.[a-z0-9\/&#95;:@=.+?,##%&~-]*[^.|\'|\# |!|\(|?|,| |>|<|;|\)])";
            Regex r = new Regex(regex, RegexOptions.IgnoreCase);
            return r.Replace(msg, "<a href=\"$1\" title=\"Click to open in a new window or tab\" target=\"&#95;blank\">$1</a>").Replace("href=\"www", "href=\"http://www");
        }
        public static string ToPhoneDigitsOnly(this string phoneNumber)
        {
            if (string.IsNullOrEmpty(phoneNumber)) { return string.Empty; }
            return phoneNumber.Replace("(", "").Replace(")", "").Replace("-", "").Replace(" ", "").Replace(".", "");
        }

        public static string ToUserOrProfileName(this Profile profile)
        {
            var nameToReturn = "";
            if (!string.IsNullOrEmpty(profile.FirstName) || !string.IsNullOrEmpty(profile.LastName))
            {
                nameToReturn = profile.FirstName.TryTrim();
                if (!string.IsNullOrEmpty(profile.LastName))
                {
                    nameToReturn += profile.LastName.TryTrim();
                }
            }
            if (string.IsNullOrEmpty(nameToReturn))
            {
                if (profile.User!=null)
                {
                    nameToReturn = profile.User.UserName;
                }
            }
            return nameToReturn;
        }

        public static string ToProfileLink(this string userName)
        {
            return "<a href='/social/profiles/" + userName + "' >" + userName + "</a>";
        }
        public static string StripTagsCharArray(this string source)
        {
            if (string.IsNullOrEmpty(source)) { return string.Empty; }
            char[] array = new char[source.Length];
            int arrayIndex = 0;
            bool inside = false;

            for (int i = 0; i < source.Length; i++)
            {
                char let = source[i];
                if (let == '<')
                {
                    inside = true;
                    continue;
                }
                if (let == '>')
                {
                    inside = false;
                    continue;
                }
                if (!inside)
                {
                    array[arrayIndex] = let;
                    arrayIndex++;
                }
            }
            return new string(array, 0, arrayIndex).Replace("&nbsp;", "  ");
        }
        public static string ToUrlFormat(this string content)
        {
            return UrlReplacementExpression.Replace(content.Trim(), String.Empty).Replace("  ", "").Replace(' ', '-').ToLowerInvariant();
        }

        public static string ToTitleCase(this string theString)
        {
            return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(theString.ToLower());
        }

        public static string ToComment(this string comment)
        {
            return "<p>" + comment.Replace("\r", "").Replace("\n", "</p><p>") + "</p>";
        }
        public static string ToSimpleZip(this string zipcode)
        {
            if (!string.IsNullOrEmpty(zipcode))
            {
                if (zipcode.Length > 4)
                {
                    return zipcode.Substring(0, 5);
                }
                else
                {
                    return zipcode;
                }
            }
            else
            {
                return string.Empty;
            }
        }
        public static string ToLast4CC(this string ccNumber)
        {
            if (!string.IsNullOrEmpty(ccNumber))
            {
                var len = ccNumber.Length;
                if (len > 3)
                {
                    return ccNumber.Substring(len - 4, 4);
                }
                else
                {
                    return "";
                }
            }
            else
            {
                return "";
            }
        }

        public static string CleanDigits(this string numberToClean)
        {
            Regex rgx = new Regex("[^a-zA-Z0-9 -]");
            numberToClean = rgx.Replace(numberToClean, "");

            if (!string.IsNullOrEmpty(numberToClean))
            {
                double Num;
                bool isNum = double.TryParse(numberToClean, out Num);
                if (isNum) { return numberToClean; }
                return null;
            }
            else
            {
                return null;
            }
        }
    }
}